import axios from 'axios'
import qs from 'qs'

// 声明一个 Map 用于存储每个请求的标识 和 取消函数
const pendingMap = new Map()

/**
 * @description: 根据 config 获取请求 identifier
 * @param {*} config - axios request config
 * @return {string} identifier 每个请求的标识
 */
const getIdentifier = (config) => {
  return [config.method, config.url, qs.stringify(config.params), qs.stringify(config.data)].join(
    '&'
  )
}

/**
 * 添加请求
 * @param {Object} config
 */
const addPending = (config) => {
  const identifier = getIdentifier(config)
  config.cancelToken =
    config.cancelToken ||
    new axios.CancelToken((cancel) => {
      if (!pendingMap.has(identifier)) {
        // 如果 pendingMap 中不存在当前请求，则添加进去
        pendingMap.set(identifier, cancel)
      }
    })
}

/**
 * 移除请求
 * @param {Object} config
 */
const removePending = (config) => {
  const identifier = getIdentifier(config)
  if (pendingMap.has(identifier)) {
    // 如果在 pendingMap 中存在当前请求标识，需要取消当前请求，并且移除
    const cancel = pendingMap.get(identifier)
    cancel(identifier)
    pendingMap.delete(identifier)
  }
}

/**
 * 清空 pendingMap 中的请求（在会话切换时调用）
 */
const clearPending = () => {
  for (const [identifier, cancel] of pendingMap) {
    cancel(identifier)
  }
  pendingMap.clear()
}

export { addPending, removePending, clearPending }
